package club.cearnach.api.service.impl;


import club.cearnach.api.dao.ICommentDao;
import club.cearnach.entity.Comment;
import club.cearnach.api.exception.CommentException;
import club.cearnach.api.form.PageBean;
import club.cearnach.api.service.ICommentService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author 阮胜
 * @date 2018/5/16 11:13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CommentServiceImpl implements ICommentService {
    private static final String UNREAD_COMMENT_LIST = "unreadCommentList";
    private final ICommentDao commentDao;
    private final StringRedisTemplate stringRedisTemplate;

    public CommentServiceImpl(ICommentDao commentDao, StringRedisTemplate stringRedisTemplate) {
        this.commentDao = commentDao;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public Page<Comment> findAll(Pageable pageable) {
        return commentDao.findAll(pageable);
    }

    @Override
    public Comment save(Comment comment) {
        return commentDao.save(comment);
    }

    @Override
    public void delete(Integer id) {
        commentDao.findById(id).orElseThrow(() -> new CommentException(CommentException.CAN_NOT_FOUND_COMMENT));
        commentDao.deleteById(id);
        ListOperations<String, String> ops = stringRedisTemplate.opsForList();
        ops.remove(UNREAD_COMMENT_LIST, 1, id.toString());
    }

    @Override
    public Page<Comment> findAllOrderByCreateDate(PageBean pageBean) {
        return commentDao.findAll(PageRequest.of(pageBean.getPage(), pageBean.getSize(), Sort.by(Sort.Direction.DESC, "createDate")));
    }

    @Override
    public Page<Comment> findByMovieId(Integer movieId, PageBean pageBean) {
        return commentDao.findByMovieId(movieId, PageRequest.of(pageBean.getPage(), pageBean.getSize(), Sort.by(Sort.Direction.DESC, "createDate")));
    }

    @Override
    public void deleteIn(Integer[] idArr) {
        for (Integer id : idArr) {
            try {
                delete(id);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public long count() {
        return commentDao.count();
    }

    @Override
    public void addUnreadComment(Integer commentId) {
        ListOperations<String, String> ops = stringRedisTemplate.opsForList();
        ops.leftPush(UNREAD_COMMENT_LIST, commentId.toString());
    }

    @Override
    public Long obtainUnreadCommentCount() {
        ListOperations<String, String> ops = stringRedisTemplate.opsForList();
        return ops.size(UNREAD_COMMENT_LIST);
    }

    @Override
    public List<Comment> obtainUnreadComments(int startIndex, int endIndex) {
        ListOperations<String, String> ops = stringRedisTemplate.opsForList();
        List<String> idList = ops.range(UNREAD_COMMENT_LIST, startIndex, endIndex);
        Integer[] ids = idList.stream().map(Integer::valueOf).toArray(Integer[]::new);
        return commentDao.findByIdIn(ids);
    }

    @Override
    public boolean clearUnreadComments() {
        return stringRedisTemplate.delete(UNREAD_COMMENT_LIST);

    }
}